package org.zoomdev.zoom.dao.driver.impl;

import org.zoomdev.zoom.common.filter.Filter;
import org.zoomdev.zoom.dao.Entity;
import org.zoomdev.zoom.dao.Record;
import org.zoomdev.zoom.dao.adapters.EntityField;
import org.zoomdev.zoom.dao.driver.SqlDriver;
import org.zoomdev.zoom.dao.impl.SimpleSqlBuilder;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

public class MysqlDriver extends SqlDriver {


    public StringBuilder protectColumn(StringBuilder sb, String name) {
        int n;
        if ((n = name.indexOf(".")) > 0) {
            String table = name.substring(0, n);
            String column = name.substring(n + 1);
            return protectName(sb, table).append(".").append(column);
        }
        return protectName(sb, name);
    }


    public String getDatabaseName(String url) {
        //jdbc:mysql://SERVER:PORT/DBNAME?useUnicode=true&characterEncoding=UTF-8
        int n = url.lastIndexOf("?");
        if (n > 0) {
            url = url.substring(0, n);
        }
        return url.substring(url.lastIndexOf("/") + 1);
    }


    public <T> void buildInsertOrUpdate(SimpleSqlBuilder builder, Entity entity, T data, Filter<EntityField> filter, boolean ignoreNull, String[] keys) {

    }


    protected StringBuilder protectName(
            StringBuilder sb, String name
    ) {
        return sb.append('`').append(name).append("`");
    }


    public void buildLimit(
            StringBuilder sql,
            List<Object> values,
            int position, int size) {

        values.add(position);
        values.add(size);
        sql.append(" LIMIT ?,?");
    }


    public void insertOrUpdate(StringBuilder sb, List<Object> values, String tableName, Record data, String[] keys) {
        StringBuilder signs = new StringBuilder();
        sb.append("INSERT INTO ")
                .append(tableName)
                .append(" (");
        boolean first = true;
        for (Entry<String, Object> entry : data.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (first) {
                first = false;
            } else {
                signs.append(',');
                sb.append(',');
            }
            sb.append(key);
            signs.append('?');
            values.add(value);
        }
        sb.append(") VALUES (").append(signs).append(") ON DUPLICATE KEY UPDATE ");
        first = true;
        Set<String> keySet = new HashSet<String>();
        Collections.addAll(keySet, keys);
        for (Entry<String, Object> entry : data.entrySet()) {
            String key = entry.getKey();
            if (keySet.contains(key)) {
                continue;
            }
            if (first) {
                first = false;
            } else {
                sb.append(',');
            }
            sb.append(key).append("=?");
            values.add(entry.getValue());
        }
    }


    public StringBuilder protect(StringBuilder sb, String name) {
        return protectColumn(sb, name);
    }


}
